/**
 * Created by no1 on 2015/11/3.
 */
'use strict';
let DD = require('./daoLoader');
let F = require('../function')
let Base = require('./Base');
let util = require("util");
let sellPermissionDao = new DD.mongoDB.SellPermissionDao;
let authorityDao = new DD.redisDB.AuthorityDao;

/**
 * 获取树结构
 * @param type
 * @returns {*}
 */
let getpermissTree = function* (type) {
  //判断redis 是否存在
  let retRedis = yield authorityDao.find('permiss:tree:' + type);
  //不存在
  if (!retRedis.data) {
    //查询mongo数据库
    let Que = {'status': 1, 'type': type}
      , arrDel = ['_id', '__v', '__t', 'createdAt', 'updateAt', 'status']
      , opt = {};
    for (let one of arrDel) opt[one] = 0;
    let retmongo = yield sellPermissionDao.getByQuery(Que, opt);
    if (retmongo.error == 1) return F.returnData(1, retmongo.msg);
    //拼接数据
    let retAss = yield assemblePermissData(retmongo.data);
    //存入redis
    yield authorityDao.save('permiss:tree:' + type, JSON.stringify(retAss));
    retRedis = yield authorityDao.find('permiss:tree:' + type);
    if (retRedis.error == 1) return [];

  }
  return JSON.parse(retRedis.data);
};
/**
 * 拼接为树结构
 * @param data
 * @returns {Array}
 */
let assemblePermissData = function*(data) {
  data = JSON.parse(JSON.stringify(data));
  let levelA = {}
    , levelB = {}
    , tmpData = []
    , tmpData2 = [];
  for (let i in data) {
    let node = data[i];
    if (0 == node.pCode) levelA[node.code] = node;
    else tmpData.push(node);
  }
  for (let i in tmpData) {
    let node = tmpData[i];
    let pCode = node.pCode;
    if (levelA[pCode]) {
      levelA[pCode].nextPer || (levelA[pCode].nextPer = []);
      levelA[pCode].nextPer.push(node);
      levelB[node.code] = node;
    }
    else tmpData2.push(node);
  }
  //for (let i in tmpData2) {
  //  let node = tmpData2[i];
  //  let pCode = node.pCode;
  //  if (levelB[pCode]) {
  //    levelB[pCode].nextCate || (levelB[pCode].nextCate = []);
  //    levelB[pCode].nextCate.push(node);
  //  }
  //}
  let retData = [];
  for (let i in levelA) retData.push(levelA[i]);
  return retData;
}
/**
 * 拼接树结构并带权限点
 * @param data
 * @param codes
 * @returns {Array}
 */
let assemblePermissDataByCodes = function*(data, codes) {
  data = JSON.parse(JSON.stringify(data));
  codes = JSON.parse(JSON.stringify(codes));
  let levelA = {}
    , levelB = {}
    , tmpData = []
    , tmpData2 = [];
  for (let i in data) {
    let node = data[i];
    if (0 == node.pCode) {
      let index = codes.indexOf(node.code)
      if (index > -1) {
        node.able = 1;
        codes.splice(index, 1);
      }
      else node.able = 0;
      levelA[node.code] = node;
    }
    else tmpData.push(node);
  }
  for (let i in tmpData) {
    let node = tmpData[i];
    let pCode = node.pCode;
    if (levelA[pCode]) {
      levelA[pCode].nextPer || (levelA[pCode].nextPer = []);

      let index = codes.indexOf(node.code)
      if (index > -1) {
        node.able = 1;
        codes.splice(index, 1);
      }
      else node.able = 0;

      levelA[pCode].nextPer.push(node);
      levelB[node.code] = node;
    }
    else tmpData2.push(node);
  }
  //for (let i in tmpData2) {
  //  let node = tmpData2[i];
  //  let pCode = node.pCode;
  //  if (levelB[pCode]) {
  //    levelB[pCode].nextCate || (levelB[pCode].nextCate = []);
  //    levelB[pCode].nextCate.push(node);
  //  }
  //}
  let retData = [];
  for (let i in levelA) retData.push(levelA[i]);
  return retData;
}

function SellPermissionDispatcher(data) {
  data = data || {};
  data.dao = data.dao || sellPermissionDao;
  data.esDao = data.esDao || {};
  data.redisDao = data.redisDao || {};
  data.modelName = data.modelName || 'sellPermission';
  data.modelType = data.modelType || 'mongo';
  this.data = data;
  Base.call(this, this.data);
};
util.inherits(SellPermissionDispatcher, Base);


/**
 * @todo 添加
 * @param fields
 * @returns {{error, msg, data}|{error, msg}}
 */
SellPermissionDispatcher.prototype.add = function*(fields) {
  if (!fields.name) return F.returnData(1, '必须有名字');
  let parameters = {};
  parameters.name = fields.name;
  parameters.pCode = fields.pCode || 0;
  parameters.type = fields.type || 0;
  parameters.status = 1;
  let ret = yield this.dao.findAndSave({code: parameters.code}, parameters, 'code');
  if (ret.error == 1) return F.returnData(1, ret.msg);
  yield authorityDao.save('permiss:tree:' + parameters.type, '');
  let json = JSON.parse(JSON.stringify(ret.data));
  let retData = F.dataFilter(json, ['_id', 'createdAt', 'updateAt', '__v', 'status'])
  return F.returnData(0, ret.msg, retData);
};

/**
 * todo 获取列表
 * @param fields
 * @returns {{error, msg, data}|{error, msg}}
 */
SellPermissionDispatcher.prototype.list = function*(fields) {
  let parameters = {}
    , retData = {};
  parameters.type = fields.type || 1;
  parameters.status = 1;
  if (fields.act == 1) retData = yield getpermissTree(parameters.type);
  return F.returnData(0, 'ok', retData);
}

/**
 * 内部调用
 * @param Que
 * @returns {{error, msg, data}|{error, msg}}
 */
SellPermissionDispatcher.prototype.findByDis = function*(Que) {
  let arrDel = ['_id', '__v', '__t', 'createdAt', 'updateAt', 'status']
    , opt = {};
  for (let one of arrDel) opt[one] = 0;
  let ret = yield  this.dao.getByQuery(Que, opt);
  if (ret.error == 1) return F.returnData(1, ret.msg, ret.data);
  return F.returnData(0, ret.msg, ret.data);
}

/**
 * 内部调用 获取树
 * @param Que
 * @returns {{error, msg, data}|{error, msg}}
 */
SellPermissionDispatcher.prototype.findTreeByDis = function*(Que) {
  let arrDel = ['_id', '__v', '__t', 'createdAt', 'updateAt', 'status']
    , opt = {};
  for (let one of arrDel) opt[one] = 0;
  let ret = yield  this.dao.getByQuery(Que, opt);
  if (ret.error == 1) return F.returnData(1, ret.msg, ret.data);
  let retAss = yield assemblePermissData(ret.data)

  return F.returnData(0, ret.msg, retAss);
}

/**
 * 内部调用 获取树并根据arr建立权限点
 * @param fields
 * @returns {{error, msg, data}|{error, msg}}
 */
SellPermissionDispatcher.prototype.AllTreeByDis = function*(fields) {
  let codes = fields.codes;
  let type = fields.type;
  let arrDel = ['_id', '__v', '__t', 'createdAt', 'updateAt', 'status']
    , opt = {};
  for (let one of arrDel) opt[one] = 0;
  let retPer = yield this.dao.getByQuery({type: type, status: 1}, opt);
  if (retPer.error == 1) F.returnData(1, retPer.msg);
  let retAss = yield assemblePermissDataByCodes(retPer.data, codes);
  return F.returnData(0, 'ok', retAss);
}

module.exports = SellPermissionDispatcher;